package com.tongjie.hotelbooking.im.message.service;

import com.tongjie.hotelbooking.im.conversation.entiry.Conversation;
import com.tongjie.hotelbooking.im.conversation.entiry.MemberConversation;
import com.tongjie.hotelbooking.im.conversation.repository.MemberConversationRepository;
import com.tongjie.hotelbooking.im.message.entiry.ImMessage;
import com.tongjie.hotelbooking.im.message.repository.ImMessageRepository;
import com.tongjie.hotelbooking.order.enums.SearchDirection;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class ImMessageService {

    @Resource
    private ImMessageRepository imMessageRepository;

    @Resource
    private MemberConversationRepository memberConversationRepository;

    public Page<ImMessage> findMessageByMemberConversationId(Long memberConversationId, Long lastId, SearchDirection searchDirection) {
        Optional<MemberConversation> memberConversationOptional = this.memberConversationRepository.findById(memberConversationId);
        if (!memberConversationOptional.isPresent()) {
            throw new RuntimeException("can not to find member conversation!");
        }

        return this.imMessageRepository.findAll(((root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(criteriaBuilder.equal(root.get("conversation"), memberConversationOptional.get().getConversation()));
            if (lastId != null) {
                predicateList.add(SearchDirection.GT.equals(searchDirection) ? criteriaBuilder.gt(root.get("id"), lastId) : criteriaBuilder.lt(root.get("id"), lastId));
            }
            return criteriaBuilder.and(predicateList.toArray(new Predicate[]{}));
        }), PageRequest.of(0, 100, Sort.by(Sort.Direction.ASC, "id")));
    }

    public Page<ImMessage> findMessageByConversationId(Long conversationId, Long lastId, SearchDirection searchDirection) {
        return this.imMessageRepository.findAll(((root, query, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(criteriaBuilder.equal(root.get("conversation"), Conversation.builder().id(conversationId).build()));
            if (lastId != null) {
                predicateList.add(SearchDirection.GT.equals(searchDirection) ? criteriaBuilder.gt(root.get("id"), lastId) : criteriaBuilder.lt(root.get("id"), lastId));
            }
            return criteriaBuilder.and(predicateList.toArray(new Predicate[]{}));
        }), PageRequest.of(0, 100, Sort.by(Sort.Direction.ASC, "id")));
    }

    @Transactional
    public void save(ImMessage imMessage) {
        this.imMessageRepository.save(imMessage);
    }

}
